import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_checking/checking/data/data.dart';
import 'package:flutter_checking/checking/radar_painter.dart';

import 'checking_widget.dart';
import 'date_picker.dart';

///
/// @author: maker
/// @date: 2021/4/15 9:50
/// description: 考勤签到
///

class Checking extends StatefulWidget {
  @override
  _CheckingState createState() => _CheckingState();
}

class _CheckingState extends State<Checking> with TickerProviderStateMixin {
  int currentIndex = 0;

  // 地址刷新
  late AnimationController controller;

  // 签到雷达
  late AnimationController radarController;

  // 签到雷达动画
  late Animation<double> animation;

  // 签到按钮时间
  late String time;

  // 是否显示签到雷达动画
  bool isShowRadar = false;

  // 开始时间
  List<Time> startTime = [];

  // 结束时间
  List<Time> endTime = [];

  // 月份和年份
  List<YearAndMonthTime> yearAndMonthTime = [];

  // 常用格式的邮箱
  List<String> emails = [];

  // 是否显示导出考勤统计底部筛选面板
  bool isShowExportFilter = false;

  // 是否显示年份和月份的时间筛选
  bool isShowMonthPicker = false;

  // 是否显示开始时间和结束时间的时间筛选
  bool isShowStartTimeAndEndTime = false;

  // 当前显示的时间筛选是否是开始时间
  bool isStartTime = false;

  // 开始时间默认索引
  int initialItem = 0;

  // 开始时间被选中时间索引
  int onSelectedValue = 0;

  // 开始时间
  String startTimeStr = "开始时间";

  // 结束时间
  String endTimeStr = "结束时间";

  // 被选中或输入后的邮箱
  String onSelectEmail = "";

  // 常用邮箱格式后缀
  List emailTail = [
    '@qq.com',
    '@163.com',
    '@126.com',
    '@sohu.com',
    '@sina.com',
    '@gmail.com'
  ];

  // 邮箱输入控制
  late TextEditingController textEditingController;

  @override
  void initState() {
    super.initState();
    controller =
        AnimationController(duration: const Duration(seconds: 1), vsync: this);

    radarController =
        AnimationController(duration: const Duration(seconds: 3), vsync: this);
    radarController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        isShowRadar = false;
        CheckingWidget().showSignDialog(context,
            CheckingWidget().getSignDialogContent(5), onTapSignConfirm);
      }
    });

    animation = Tween(begin: .0, end: pi * 2).animate(radarController);

    time = CheckingWidget().getCurrentTime(DateTime.now());
    // 当前时间
    Timer.periodic(Duration(seconds: 1), (timer) async {
      if (currentIndex == 0) {
        time = CheckingWidget().getCurrentTime(DateTime.now());
        print("time:$time");
        setState(() {});
      }
    });

    /// 计算开始时间
    startTime = CheckingWidget().calculateStartTime(DateTime.now());

    /// 添加我的考勤统计右侧只含年月时间
    yearAndMonthTime = CheckingWidget().calculateMonths(DateTime.now());
    initialItem = startTime.length - startTime.last.day;

    /// 初始化邮箱输入
    textEditingController = TextEditingController.fromValue(TextEditingValue(
        // 设置内容
        text: onSelectEmail,
        // 保持光标在最后
        selection: TextSelection.fromPosition(TextPosition(
            affinity: TextAffinity.downstream, offset: onSelectEmail.length))));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Stack(
        children: [
          // 标题
          CheckingWidget()
              .buildCheckingAppBar(context, onTapSignStatisticsExport),
          // 底部按钮
          CheckingWidget()
              .buildCheckingBottomButton(currentIndex, onTapButtonButton),
          // 0 ： 签到    1：考勤统计
          currentIndex == 0
              ? CheckingWidget().buildSignContainer(
                  context,
                  // 考勤地址
                  CheckingWidget().buildSignLocation(
                      "浙江省杭州市西湖区南山路32号",
                      RotationTransition(
                        turns: controller,
                        child: CheckingWidget()
                            .buildSignRefreshButton(onTapRefreshLocation),
                      )),
                  // 考勤按钮
                  CheckingWidget().buildSignButton(
                      DateTime.now().hour,
                      time,
                      1,
                      Visibility(
                        visible: isShowRadar,
                        child: AnimatedBuilder(
                            animation: animation,
                            builder: (context, child) {
                              return Container(
                                height: 144.0,
                                width: 144.0,
                                child: CustomPaint(
                                  painter: RadarPainter(animation.value),
                                ),
                              );
                            }),
                      ),
                      onTapSign))
              : CheckingWidget().buildSignStatisticsContainer(context, [
                  // 我的考勤痛统计
                  CheckingWidget().buildSignStatisticsHeader(
                      yearAndMonthTime.last.toString(), false, onTapDateFilter),
                  // 考勤日历
                  DatePickerDialog(
                    initialDate: DateTime.now(),
                    firstDate: DateTime(2020),
                    lastDate: DateTime(2030),
                    onDateChanged: onDateChanged,
                    // 0：无状态，1：正常考勤  2：异常考情，迟到，早退，若不满一个月，
                    // 日历会自动已0补满一个月
                    checking: [
                      0,
                      0,
                      1,
                      2,
                      1,
                      2,
                      0,
                      1,
                      2,
                      1,
                      1,
                      1,
                      1,
                      2,
                      2,
                      2,
                      0,
                      0,
                      0,
                      2,
                      1
                    ],
                  ),
                  // 某一天考勤详细情况
                  CheckingWidget().buildSignStatisticOfOneDay()
                ]),

          /// 导出考勤统计，包含开始时间，结束时间，邮箱输入
          Align(
            alignment: Alignment.bottomCenter,
            child: Visibility(
                visible: isShowExportFilter,
                child: CheckingWidget().showSignStatisticsBottomSheet(
                    context,
                    startTimeStr,
                    endTimeStr,
                    onSelectEmail,
                    emails,
                    textEditingController,
                    onTapStartTime,
                    onTapEndTime,
                    onTapSignStatisticsCancel,
                    onTapSignStatisticsConfirm,
                    onTapEmailItem,
                    onEmailChanged)),
          ),

          /// 开始时间，结束时间，默认从当前所在月份1日开始，最早开始于2020-06-01，结束时间与
          /// 用户选择的开始时间最大跨度不能超过一个月
          Align(
            alignment: Alignment.bottomCenter,
            child: Visibility(
                visible: isShowStartTimeAndEndTime,
                child: CheckingWidget().showSignStatisticsExportPicker(
                  context,
                  startTime,
                  endTime,
                  initialItem,
                  isStartTime,
                  onTapCancel,
                  onTapConfirm,
                )),
          ),

          /// 我的考勤右侧只有月份和年份的时间筛选
          Align(
            alignment: Alignment.bottomCenter,
            child: Visibility(
                visible: isShowMonthPicker,
                child: CheckingWidget().showSignStatisticsTopTimePicker(
                    context,
                    yearAndMonthTime,
                    onTapMonthCancel,
                    onTapMonthConfirm,
                    onMonthChanged)),
          ),
        ],
      ),
    );
  }

  /// 签到统计导出,若有其他悬浮的弹框,统统置为false，隐藏状态
  onTapSignStatisticsExport() {
    print("签到统计导出");
    isShowMonthPicker = false;
    isShowStartTimeAndEndTime = false;
    // startTimeStr = "开始时间";
    // endTimeStr = "结束时间";
    // isStartTime = true;
    isShowExportFilter = true;
    setState(() {});
  }

  /// 签到和考勤统计底部按钮
  /// 0 : 签到    1：考勤统计
  onTapButtonButton(int value) {
    print("onTapButtonButton$value");
    if (currentIndex != value) {
      currentIndex = value;
      setState(() {});
    }
  }

  /// 刷新地址-动画开始时重新开始获取当前位置信息
  onTapRefreshLocation() {
    print("onTapRefreshLocation");
    if (controller.status == AnimationStatus.completed) {
      controller.reset();
      controller.forward();
    } else {
      controller.forward();
    }
  }

  /// 点击签到，若上午时间晚于9点，则为迟到，下午早于6点，则为早退，若当天无签到，则一直为迟到状态
  /// 点击按钮后执行动画，并请求签到接口，根据接口状态，展示不同的弹框内容
  onTapSign() {
    print("onTapSign");
    isShowRadar = true;
    radarController.reset();
    radarController.forward();
  }

  /// 签到完成后，展示不同的提示语，点击弹窗中确认按钮弹窗消失
  onTapSignConfirm() {
    print("onTapSignConfirm");
    Navigator.pop(context);
  }

  /// 我的考勤统计顶部时间筛选，只包含年月
  onTapDateFilter() {
    print("onTapDateFilter");
    isShowStartTimeAndEndTime = false;
    isShowExportFilter = false;
    isShowMonthPicker = true;
    setState(() {});
  }

  /// 签到功能导出-时间筛选（开始时间、结束时间）-确认
  /// 开始时间和结束时间共用一个时间筛选
  /// isStartTime      true  开始时间    false结束时间
  /// value     被选中时间对于的索引
  onTapConfirm(value) {
    onSelectedValue = value;
    isShowExportFilter = false;
    if (isStartTime) {
      startTimeStr = startTime[value].toString();
    } else {
      endTimeStr = endTime[value].toString();
    }
    print(
        "${isStartTime ? "开始时间：" : "结束时间:"} : ${isStartTime ? startTimeStr : endTimeStr}");
    setState(() {});
  }

  /// 签到功能导出-时间筛选（开始时间、结束时间）-取消
  onTapCancel() {
    print("onTapCancel");
    isShowExportFilter = false;
    setState(() {});
  }

  /// 我的考勤统计顶部时间筛选，被选中的时间
  void onMonthChanged(value) {
    print("onMonthChanged${yearAndMonthTime[value].toString()}");
  }

  /// 我的考勤统计顶部时间筛选，确认
  onTapMonthConfirm() {
    print("onTapMonthConfirm");
    isShowMonthPicker = false;
    setState(() {});
  }

  /// 我的考勤统计顶部时间筛选，取消
  onTapMonthCancel() {
    print("onTapMonthConfirm");
    isShowMonthPicker = false;
    setState(() {});
  }

  /// 导出考勤统计-取消
  onTapSignStatisticsCancel() {
    isShowExportFilter = false;
    isShowStartTimeAndEndTime = false;
    isShowMonthPicker = false;
    isStartTime = true;
    startTimeStr = "开始时间";
    endTimeStr = "结束时间";
    setState(() {});
  }

  /// 导出考勤统计-确认
  onTapSignStatisticsConfirm() {
    /// 是否选择开始时间
    if (startTimeStr.isEmpty || startTimeStr == "开始时间") {
      print("请选择开始时间");
      return;
    }

    /// 是否选择结束时间
    if (endTimeStr.isEmpty || endTimeStr == "结束时间") {
      print("请选择结束时间");
      return;
    }

    /// 是否输入邮箱地址
    if (onSelectEmail.isEmpty) {
      print("请输入邮箱");
      return;
    }

    /// 邮箱地址格式判断
    String regexEmail = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$";
    if (!RegExp(regexEmail).hasMatch(onSelectEmail)) {
      print("请输入正确格式的邮箱");
      return;
    }

    /// 以上条件均满足，则请求导出考勤统计api
  }

  onTapStartTime() {
    isShowStartTimeAndEndTime = true;
    isStartTime = true;
    setState(() {});
  }

  /// 点击结束时间时，需要先选择开始时间，因为结束时间是由开始时间计算得来的，距离开始时间
  /// 最大跨度不得超过一个月
  onTapEndTime() {
    if (startTimeStr == "开始时间") {
      print("请先选择开始时间");
      return;
    }
    endTime = CheckingWidget().calculateEndTime(startTime[onSelectedValue]);
    isShowStartTimeAndEndTime = true;
    isStartTime = false;
    setState(() {});
  }

  /// 从推荐的邮箱地址中选中，选中之后清空推荐选项，并保存光标在最后
  onTapEmailItem(value) {
    print("onTapEmailItem:$value");
    onSelectEmail = value.toString();
    emails.clear();
    textEditingController.text = onSelectEmail;
    textEditingController.selection = TextSelection.fromPosition(TextPosition(
        affinity: TextAffinity.downstream, offset: onSelectEmail.length));
    setState(() {});
  }

  /// 用户输入邮箱后自动提供常用的几种邮箱地址格式，当输入的内容中包含@后不再进行提示
  void onEmailChanged(value) {
    print("onEmailChanged:$value");
    emails.clear();
    onSelectEmail = value;
    String email = value.toString();
    if (!email.contains("@")) {
      emailTail.forEach((tail) {
        emails.add(email + tail);
      });
      setState(() {});
    }
  }

  /// 考勤统计日历中，被选中的日期，请求api，获取当日考勤详情情况
  void onDateChanged(DateTime value) {
    print("onDateChanged:${value.year}-${value.month}-${value.day}");
  }

  @override
  void dispose() {
    radarController.dispose();
    controller.dispose();
    super.dispose();
  }
}
